package org.megha.blog.example.part16;

import junit.framework.Assert;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.megha.blog.example.part16.StereoSystem.State;

public class StereoSystemTest {

	private StereoSystem stereoSystem;

	public StereoSystemTest() {
		System.out.println("in constructor");
	}

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		System.out.println("Set up before class");
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
		System.out.println("tear down after class");
	}

	@Before
	public void setUp() throws Exception {
		System.out.println("set up");
		stereoSystem = new StereoSystem();
	}

	@After
	public void tearDown() throws Exception {
		System.out.println("tear down");
	}

	@Test
	public void sanityOfNewInstance() {
		System.out.println("sanity Of New Instance");
		Assert.assertEquals(State.STOPPED, stereoSystem.getCurrentState());
	}

	@Test
	public void playStopStateTransitions() {
		System.out.println("Play Stop state transitions test");
		playAndVerify();
		stopAndVerify();
		playAndVerify();
		stopAndVerify();
	}

	@Test
	public void recordStopStateTransisitons() {
		System.out.println("Record and stop state transitions test");
		recordAndVerify();
		stopAndVerify();
		recordAndVerify();
		stopAndVerify();
	}

	@Test
	public void playRecordStopStateTransitions() {
		System.out.println("Record and Stop; Play and Stop transition test");
		playAndVerify();
		stopAndVerify();
		recordAndVerify();
		stopAndVerify();
		playAndVerify();
	}

	@Test(expected = IllegalStateException.class)
	public void cannotRecordWhilePlaying() {
		System.out.println("cannot record while playing test");
		playAndVerify();
		stereoSystem.record(); // should throw exception
	}

	@Test(expected = IllegalStateException.class)
	public void cannotPlayWhileRecording() {
		System.out.println("cannot play while recording test");
		recordAndVerify();
		stereoSystem.play(); //should throw an exception
	}

	private void playAndVerify() {
		stereoSystem.play();
		Assert.assertEquals(State.PLAYING, stereoSystem.getCurrentState());
	}

	private void recordAndVerify() {
		stereoSystem.record();
		Assert.assertEquals(State.RECORDING, stereoSystem.getCurrentState());
	}

	private void stopAndVerify() {
		stereoSystem.stop();
		Assert.assertEquals(State.STOPPED, stereoSystem.getCurrentState());
	}
}
